package cn.gemiman.daoyi.module.iot.service.userequipment;

import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.module.iot.controller.admin.userequipment.vo.UserEquipmentPageReqVO;
import cn.gemiman.daoyi.module.iot.controller.admin.userequipment.vo.UserEquipmentSaveReqVO;
import cn.gemiman.daoyi.module.iot.dal.dataobject.userequipment.UserEquipmentDO;
import cn.gemiman.daoyi.module.iot.dal.dataobject.userequipmentplace.UserEquipmentPlaceDO;
import cn.gemiman.daoyi.module.iot.dal.mysql.jhlequipmentdevice.JhlEquipmentDeviceMapper;
import cn.gemiman.daoyi.module.iot.dal.mysql.userequipment.UserEquipmentMapper;
import cn.gemiman.daoyi.module.iot.dal.mysql.userequipmentplace.UserEquipmentPlaceMapper;
import cn.gemiman.daoyi.module.member.api.user.MemberUserApi;
import cn.gemiman.daoyi.module.member.api.user.dto.MemberUserRespDTO;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.Optional;

import static cn.gemiman.daoyi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.gemiman.daoyi.module.iot.enums.ErrorCodeConstants.*;

/**
 * 会员设备 Service 实现类
 *
 * @author 道一源码
 */
@Service
@Validated
public class UserEquipmentServiceImpl implements UserEquipmentService {

    @Resource
    private UserEquipmentMapper userEquipmentMapper;
    @Resource
    private JhlEquipmentDeviceMapper jhlEquipmentDeviceMapper;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private UserEquipmentPlaceMapper userEquipmentPlaceMapper;

    @Override
    public Long createUserEquipment(UserEquipmentSaveReqVO createReqVO) {
        if (userEquipmentMapper.exists(Wrappers.lambdaQuery(UserEquipmentDO.class)
                .eq(UserEquipmentDO::getEquipmentManufacturer, createReqVO.getEquipmentManufacturer())
                .eq(UserEquipmentDO::getEquipmentId, createReqVO.getEquipmentId())
        )) {
            throw exception(USER_EQUIPMENT_EXISTS);
        }
        UserEquipmentPlaceDO placeDO = userEquipmentPlaceMapper.selectById(createReqVO.getPlaceId());
        if (placeDO == null) {
            throw exception(USER_EQUIPMENT_PLACE_NOT_EXISTS);
        }
        if (!placeDO.getMemberUserId().equals(createReqVO.getMemberUserId())) {
            throw exception(USER_EQUIPMENT_PLACE_NOT_MATCH);
        }
        // 插入
        UserEquipmentDO userEquipment = BeanUtils.toBean(createReqVO, UserEquipmentDO.class);
        userEquipmentMapper.insert(userEquipment);
        // 返回
        return userEquipment.getId();
    }

    @Override
    public void updateUserEquipment(UserEquipmentSaveReqVO updateReqVO) {
        // 校验存在
        UserEquipmentDO exists = validateUserEquipmentExists(updateReqVO.getId());
        updateReqVO.setMemberUserId(exists.getMemberUserId());
        if (userEquipmentMapper.exists(Wrappers.lambdaQuery(UserEquipmentDO.class)
                .eq(UserEquipmentDO::getEquipmentManufacturer, updateReqVO.getEquipmentManufacturer())
                .eq(UserEquipmentDO::getEquipmentId, updateReqVO.getEquipmentId())
                .ne(UserEquipmentDO::getId, updateReqVO.getId())
        )) {
            throw exception(USER_EQUIPMENT_EXISTS);
        }
        UserEquipmentPlaceDO placeDO = userEquipmentPlaceMapper.selectById(updateReqVO.getPlaceId());
        if (placeDO == null) {
            throw exception(USER_EQUIPMENT_PLACE_NOT_EXISTS);
        }
        if (!placeDO.getMemberUserId().equals(updateReqVO.getMemberUserId())) {
            throw exception(USER_EQUIPMENT_PLACE_NOT_MATCH);
        }
        // 更新
        UserEquipmentDO updateObj = BeanUtils.toBean(updateReqVO, UserEquipmentDO.class);
        userEquipmentMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserEquipment(Long id, Long userId) {
        // 校验存在
        UserEquipmentDO userEquipmentDO = validateUserEquipmentExists(id);
        if (!userEquipmentDO.getMemberUserId().equals(userId)) {
            throw exception(USER_EQUIPMENT_NOT_EXISTS);
        }
        // 删除
        userEquipmentMapper.deleteById(id);
    }

    @Override
    public void deleteUserEquipment(Long id) {
        // 校验存在
        validateUserEquipmentExists(id);
        // 删除
        userEquipmentMapper.deleteById(id);
    }

    private UserEquipmentDO validateUserEquipmentExists(Long id) {
        UserEquipmentDO userEquipmentDO = userEquipmentMapper.selectById(id);
        if (userEquipmentDO == null) {
            throw exception(USER_EQUIPMENT_NOT_EXISTS);
        }
        return userEquipmentDO;
    }

    @Override
    public UserEquipmentDO getUserEquipment(Long id) {
        UserEquipmentDO userEquipmentDO = userEquipmentMapper.selectById(id);
        if (null != userEquipmentDO) {
            Optional.ofNullable(jhlEquipmentDeviceMapper.selectById(userEquipmentDO.getEquipmentId())).ifPresent(jhlEquipmentDeviceDO -> {
                userEquipmentDO.setEquipment(JSONUtil.parseObj(jhlEquipmentDeviceDO));
            });
            MemberUserRespDTO checkedData = memberUserApi.getUser(userEquipmentDO.getMemberUserId()).getCheckedData();
            userEquipmentDO.setMemberUser(checkedData);
            Optional.ofNullable(userEquipmentPlaceMapper.selectById(userEquipmentDO.getPlaceId())).ifPresent(userEquipmentDO::setPlace);
        }
        return userEquipmentDO;
    }

    @Override
    public PageResult<UserEquipmentDO> getUserEquipmentPage(UserEquipmentPageReqVO pageReqVO) {
        PageResult<UserEquipmentDO> userEquipmentDOPageResult = userEquipmentMapper.selectPage(pageReqVO);
        List<UserEquipmentDO> list = userEquipmentDOPageResult.getList();
        if (CollUtil.isNotEmpty(list)) {
            jhlEquipmentDeviceMapper.selectBatchIds(list.stream().map(UserEquipmentDO::getEquipmentId).toList())
                    .forEach(jhlEquipmentDeviceDO -> list.stream()
                            .filter(userEquipmentDO -> userEquipmentDO.getEquipmentId().equals(Long.parseLong(jhlEquipmentDeviceDO.getId().toString())))
                            .forEach(userEquipmentDO -> userEquipmentDO.setEquipment(JSONUtil.parseObj(jhlEquipmentDeviceDO)))
                    );
            memberUserApi.getUserList(list.stream().map(UserEquipmentDO::getMemberUserId).toList()).getCheckedData()
                    .forEach(memberUserRespDTO -> list.stream()
                            .filter(userEquipmentDO -> userEquipmentDO.getMemberUserId().equals(memberUserRespDTO.getId()))
                            .forEach(userEquipmentDO -> userEquipmentDO.setMemberUser(memberUserRespDTO))
                    );
            userEquipmentPlaceMapper.selectBatchIds(list.stream().map(UserEquipmentDO::getPlaceId).toList())
                    .forEach(userEquipmentPlaceDO -> list.stream()
                            .filter(userEquipmentDO -> userEquipmentDO.getPlaceId().equals(userEquipmentPlaceDO.getId()))
                            .forEach(userEquipmentDO -> userEquipmentDO.setPlace(userEquipmentPlaceDO))
                    );
        }
        return userEquipmentDOPageResult;
    }

}
